package com.itc.bpm.service.impl;

import com.itc.bpm.dto.QuartzJobDto;
import com.itc.bpm.framework.quartz.TaskJob;
import com.itc.bpm.service.QuartzService;
import io.swagger.annotations.ApiOperation;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 流程定时任务调度类
 */
@Service
public class QuartzServiceImpl implements QuartzService {

    @Autowired
    private Scheduler scheduler;

    /**
     * 定时任务_创建
     * @param quartzJobDto
     * @throws Exception
     */
    @ApiOperation(value = "定时任务_创建", notes = "创建")
    public void startTaskJob( QuartzJobDto quartzJobDto) throws Exception {
        Date start=new Date(System.currentTimeMillis() + 7 * 1000);//当前时间7秒之后

        /**通过JobBuilder.newJob()方法获取到当前Job的具体实现(以下均为链式调用)
         * 这里是固定Job创建，所以代码写死XXX.class
         * 如果是动态的，根据不同的类来创建Job，则 ((Job)Class.forName("com.zy.job.TestJob").newInstance()).getClass()
         * 即是 JobBuilder.newJob(((Job)Class.forName("com.zy.job.TestJob").newInstance()).getClass())
         * */
        JobDetail jobDetail = JobBuilder.newJob(TaskJob.class)
                /**给当前JobDetail添加参数，K V形式*/
                .usingJobData("taskName",quartzJobDto.getTaskName())
                /**给当前JobDetail添加参数，K V形式，链式调用，可以传入多个参数，在Job实现类中，可以通过jobExecutionContext.getJobDetail().getJobDataMap().get("age")获取值*/
                .usingJobData("processInstanceId",quartzJobDto.getProcessInstanceId())
                .usingJobData("taskId",quartzJobDto.getTaskId())
                /**添加认证信息，有3种重写的方法，我这里是其中一种，可以查看源码看其余2种*/
                .withIdentity(quartzJobDto.getTaskId())
                .build();//执行


        Trigger trigger = TriggerBuilder.newTrigger()
                /**给当前JobDetail添加参数，K V形式，链式调用，可以传入多个参数，在Job实现类中，可以通过jobExecutionContext.getTrigger().getJobDataMap().get("orderNo")获取值*/
                .usingJobData("taskId", quartzJobDto.getTaskId())
                /**添加认证信息，有3种重写的方法，我这里是其中一种，可以查看源码看其余2种*/
                .withIdentity(quartzJobDto.getTaskId())
                /**立即生效*/
//      .startNow()
                /**开始执行时间*/
                .startAt(start)
                /**结束执行时间*/
//        .endAt(start)
                /**添加执行规则，SimpleTrigger、CronTrigger的区别主要就在这里*/
                .withSchedule(
                        SimpleScheduleBuilder.simpleSchedule()
                                /**每隔多少分钟执行一次*/
                                .withIntervalInMinutes(quartzJobDto.getMinute())
                                /**一直执行，*/
                                .repeatForever()
                )
                .build();//执行



        /**添加定时任务*/
        scheduler.scheduleJob(jobDetail, trigger);
        if (!scheduler.isShutdown()) {
            /**启动*/
            scheduler.start();
        }
    }

    /**
     *停止定时任务
     * @param taskId
     * @throws SchedulerException
     */
    public void shutdown(String taskId) throws SchedulerException {
        scheduler.pauseTrigger(TriggerKey.triggerKey(taskId));//暂停Trigger
    }

    /**
     * 删除定时任务
     * @param taskId
     * @throws IOException
     * @throws SchedulerException
     */
    public void del(String taskId) throws IOException, SchedulerException {
        scheduler.pauseTrigger(TriggerKey.triggerKey(taskId));//暂停触发器
        scheduler.unscheduleJob(TriggerKey.triggerKey(taskId));//移除触发器
        scheduler.deleteJob(JobKey.jobKey(taskId));//删除Job
    }
}


